<template>
    <a-modal v-model:visible="visible" :on-before-ok="submit" @cancel="close">
        <template #title>{{ $t('chan-pin-shu-xing') }}</template>
        <div>
            <a-form ref="formRef" :model="formData" :rules="formRules">
                <a-form-item field="name" :label="$t('shu-xing-ming-cheng')">
                    <a-input v-model="formData.name"></a-input>
                </a-form-item>
                <a-form-item
                    field="identifier"
                    :label="$t('product.model.flag')"
                >
                    <a-input v-model="formData.identifier"></a-input>
                </a-form-item>
                <a-form-item
                    field="datatype"
                    :label="$t('product.model.dataType')"
                >
                    <a-select
                        v-model="formData.datatype"
                        @change="changeDatatype"
                    >
                        <a-option
                            v-for="option in DATA_TYPE_OPTIONS"
                            :key="option.value"
                            :label="option.label"
                            :value="option.value"
                        ></a-option>
                    </a-select>
                </a-form-item>
                <a-form-item field="specs" hide-label>
                    <data-type
                        ref="dataTypeRef"
                        v-model="formData.specs"
                        :type="formData.datatype"
                    />
                </a-form-item>
                <a-form-item field="sort" :label="$t('pai-xu')">
                    <a-input-number
                        v-model="formData.sort"
                        :precision="0"
                        :min="0"
                        model-event="input"
                    />
                </a-form-item>
                <a-form-item field="icon" label="icon">
                    <a-input
                        v-model="formData.icon"
                        :placeholder="$t('qing-shu-ru-icon')"
                    />
                </a-form-item>
                <a-form-item field="remark" :label="$t('bei-zhu')">
                    <a-textarea
                        v-model="formData.remark"
                        :placeholder="$t('qing-shu-ru-bei-zhu')"
                        allow-clear
                        auto-size
                    />
                </a-form-item>
            </a-form>
        </div>
    </a-modal>
</template>

<script lang="ts" setup>
    import { ref, reactive, PropType } from 'vue';
    import { pick } from 'lodash';
    import { useI18n } from 'vue-i18n';
    import DataType from './data-type.vue';
    import { DATA_TYPE, DATA_TYPE_OPTIONS } from './const';
    import {
        getProductModelDetail,
        addProductModel,
        editProductModel,
    } from './service';

    function transformEnumData(data: Record<string, string>) {
        return Object.entries(data).map(([key, value]) => ({
            key,
            value,
        }));
    }

    function transformListToMap(data: any[]) {
        return data.reduce((acc, cur) => {
            acc[cur.key] = cur.value;
            return acc;
        }, {});
    }
    const { t } = useI18n();

    const props = defineProps({
        title: {
            type: String,
            default: '',
        },
        type: {
            type: String as PropType<'ADD' | 'EDIT'>,
            default: 'ADD',
        },
        productId: {
            type: String,
            default: '',
        },
        id: {
            type: String,
            default: '',
        },
    });
    const emit = defineEmits(['submit']);

    const visible = ref(false);
    const formRef = ref();
    const dataTypeRef = ref();
    const getDefaultSpecs = (type: string) => {
        switch (type) {
            case DATA_TYPE.BOOLEAN:
                return {
                    0: '',
                    1: '',
                };
            case DATA_TYPE.STRING:
                return {};
            case DATA_TYPE.ENUM:
                return [
                    {
                        key: '',
                        value: '',
                    },
                ];
            case DATA_TYPE.INTEGER:
                return {
                    min: undefined,
                    max: undefined,
                    unit: '',
                    unitName: '',
                };
            case DATA_TYPE.DECIMAL:
                return {
                    min: undefined,
                    max: undefined,
                    unit: '',
                    unitName: '',
                };
            default:
                return undefined;
        }
    };
    const formData = reactive({
        productId: props.productId,
        name: '',
        identifier: '',
        datatype: DATA_TYPE.INTEGER,
        specs: getDefaultSpecs(DATA_TYPE.INTEGER),
        sort: undefined,
        icon: undefined,
        remark: '',
    });
    const formRules = {
        name: [
            {
                required: true,
                message: t('qing-shu-ru-shu-xing-ming-cheng'),
            },
        ],
        identifier: [{ required: true, message: t('qing-shu-ru-biao-shi-fu') }],
        datatype: [
            {
                required: true,
                message: t('qing-xuan-ze-shu-ju-lei-xing'),
            },
        ],
        specs: [
            {
                async validator(_val: any, cb: any) {
                    try {
                        await dataTypeRef.value.validate();
                        cb();
                    } catch {
                        cb('');
                    }
                },
            },
        ],
        sort: [{ required: true, message: t('qing-shu-ru-pai-xu') }],
        icon: [{ required: false, message: t('qing-shu-ru-icon-0') }],
        remark: [{ required: false, message: t('qing-shu-ru-bei-zhu') }],
    };

    function changeDatatype(type: string) {
        formData.specs = getDefaultSpecs(type);
    }

    async function open() {
        if (props.type === 'EDIT') {
            const { result } = await getProductModelDetail({
                id: props.id,
            });
            const specs =
                result.datatype === DATA_TYPE.ENUM
                    ? transformEnumData(result.specs)
                    : result.specs;
            Object.assign(
                formData,
                pick(result, [
                    'id',
                    'name',
                    'identifier',
                    'productId',
                    'datatype',
                    'sort',
                    'icon',
                    'remark',
                ]),
                { specs }
            );
        }
        visible.value = true;
    }

    function close() {
        formRef.value.resetFields();
        visible.value = false;
    }

    async function submit() {
        const res = await formRef.value.validate();
        const payload = {
            ...formData,
            specs:
                formData.datatype === DATA_TYPE.ENUM
                    ? transformListToMap(formData.specs)
                    : formData.specs,
        };
        if (!res) {
            if (props.type === 'ADD') {
                await addProductModel(payload);
            } else {
                await editProductModel(payload);
            }
            emit('submit');
            formRef.value.resetFields();
            return true;
        }
        return false;
    }

    defineExpose({
        open,
    });
</script>
